
import numpy as np

samples_and = [
    [0, 0, 0],
    [1, 0, 0],
    [0, 1, 0],
    [1, 1, 1],
]
'''
0xw1 + 0xw2 + b <= 0
1xw1 + 0xw2 + b <= 0
0xw1 + 1xw2 + b <= 0
1xw1 + 1xw2 + b >  0

输入的x1,x2,对应坐标轴的点即为（0,0), (1,0), (0,1),(1,1)
因为结果只有一个点（1,1）y=1，其余都为0，在坐标轴上即可以画一条线把结果0，1区分开，满足线性可分的线，即为w1, w2, b 的值 

'''

samples_or = [
    [0, 0, 0],
    [1, 0, 1],
    [0, 1, 1],
    [1, 1, 1],
]

'''
0xw1 + 0xw2 + b <= 0
1xw1 + 0xw2 + b >  0
0xw1 + 1xw2 + b >  0
1xw1 + 1xw2 + b >  0

输入的x1,x2,对应坐标轴的点即为（0,0), (1,0), (0,1),(1,1)
因为结果只有一个点（0,0）时y=0，其余都为1，在坐标轴上即可以画一条线把结果0，1区分开，满足线性可分的线，即为w1, w2, b 的值 
'''

samples_xor = [
    [0, 0, 0],
    [1, 0, 1],
    [0, 1, 1],
    [1, 1, 0],
]

'''
0xw1 + 0xw2 + b <= 0
1xw1 + 0xw2 + b >  0
0xw1 + 1xw2 + b >  0
1xw1 + 1xw2 + b <= 0

输入的x1,x2,对应坐标轴的点即为（0,0), (1,0), (0,1),(1,1)
因为结果（1,1）和（0,0）时y=0，(1,0)和(0,1)时y=1，值为0和值为1的区域线性不可分，故感知器无法模拟xor运算。
'''



def perceptron(samples):
    w = np.array([1, 2])
    b = 0
    a = 1
    #循环10次
    for i in range(10):
        #检查每一行的值
        for j in range(4):
            x = np.array(samples[j][:2]) #x 取前两列
            y = 1 if np.dot(w, x) + b > 0 else 0 #阶跃函数
            d = np.array(samples[j][2])  #真实值

            delta_b = a*(d-y)  #-(t-y)
            delta_w = a*(d-y)*x #-(t-y)*x

            print('epoch {} sample {}  [{} {} {} {} {} {} {}]'.format(
                i, j, w[0], w[1], b, y, delta_w[0], delta_w[1], delta_b
            ))
            w = w + delta_w #更新w值
            b = b + delta_b #更新b值


if __name__ == '__main__':
    print('logical and')
    perceptron(samples_and)
    print("="*40)
    print('logical or')
    perceptron(samples_or)
    print("="*40)
    print('logical xor')
    perceptron(samples_xor)
